package com.mall.common.result;

import lombok.Data;
import java.io.Serializable;

@Data
public class Result<T> implements Serializable {
    private static final long serialVersionUID = 1L;
    private Integer code;
    private String message;
    private T data;

    // 默认构造：使用成功状态码（需确保ResultCode.SUCCESS非空）
    public Result() {
        this.code = ResultCode.SUCCESS.getCode();
    }

    // 成功：带数据
    public static <T> Result<T> success(T data) {
        Result<T> result = new Result<>();
        result.setCode(ResultCode.SUCCESS.getCode());
        result.setData(data);
        return result;
    }

    // 成功：无数据（使用Void）
    public static Result<Void> success() {
        return success(null);
    }

    // 成功：带消息（无数据）
    public static Result<Void> successMsg(String message) {
        Result<Void> result = new Result<>();
        result.setCode(ResultCode.SUCCESS.getCode());
        result.setMessage(message); // 设置消息
        return result;
    }

    // 成功：带数据和消息
    public static <T> Result<T> success(T data, String message) {
        Result<T> result = new Result<>();
        result.setCode(ResultCode.SUCCESS.getCode());
        result.setData(data);
        result.setMessage(message);
        return result;
    }

    // 错误：基于错误码枚举
    public static <T> Result<T> error(IResultCode enums) {
        return error(enums.getCode(), enums.getMessage());
    }

    // 错误：基于枚举+自定义消息
    public static <T> Result<T> error(IResultCode enums, String message) {
        return error(enums.getCode(), message);
    }

    // 错误：指定错误码和消息（支持泛型数据，用于特殊场景）
    public static <T> Result<T> error(int code, String message) {
        return error(code, message, null); // 默认无数据
    }

    // 错误：带数据（扩展方法，用于需要返回错误数据的场景）
    public static <T> Result<T> error(int code, String message, T data) {
        Result<T> result = new Result<>();
        result.setCode(code);
        result.setMessage(message);
        result.setData(data); // 错误时也可以返回数据
        return result;
    }

    // 链式方法
    public Result<T> code(Integer code) {
        this.code = code;
        return this;
    }
    public Result<T> msg(String message) {
        this.message = message;
        return this;
    }
    public Result<T> data(T data) {
        this.data = data;
        return this;
    }
}